<#-- assign -->
<#assign modelClass="com.github.freegeese.maven.plugin.autocode.demo.model.${table.modelName}">
<#assign mapperClass="com.github.freegeese.maven.plugin.autocode.demo.mapper.${table.modelName}Mapper">
<#assign idColumn=table.idColumn>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${mapperClass}">
    <resultMap id="BaseResultMap" type="${modelClass}">
        <id column="${idColumn.columnName}" jdbcType="${idColumn.jdbcType}" property="${idColumn.property}" />
        <#list table.filteredColumns as column>
        <result column="${column.columnName}" jdbcType="${column.jdbcType}" property="${column.property}" />
        </#list>
    </resultMap>

    <sql id="Base_Column_List">
        ${table.baseColumnList}
    </sql>

    <#-- insert -->
    <insert id="insert" keyProperty="${idColumn.property}" useGeneratedKeys="true">
        insert into ${table.tableName} (${table.insertColumnList})
        values (${table.insertValues})
    </insert>

    <insert id="insertSelective" keyProperty="${idColumn.property}" useGeneratedKeys="true">
        insert into ${table.tableName}
        <trim prefix="(" suffix=")" suffixOverrides=",">
        <#list table.insertSelectiveColumnList as column>
            <if test="${column.property} != null">
                ${column.columnName},
            </if>
        </#list>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
        <#list table.insertSelectiveColumnList as column>
            <if test="${column.property} != null">
                ${'#\{'}${column.columnName},jdbcType=${column.jdbcType}},
            </if>
        </#list>
        </trim>
    </insert>

    <#-- delete -->
    <delete id="deleteByPrimaryKey" parameterType="${idColumn.javaType.name}">
        delete from ${table.tableName}
        where ${idColumn.columnName} = ${'#\{'}${idColumn.property},jdbcType=${idColumn.jdbcType}}
    </delete>

    <delete id="deleteByPrimaryKeys">
        delete from ${table.tableName} where ${idColumn.columnName} in
        <foreach close=")" collection="list" item="item" open="(" separator=",">
        ${'#\{'}item}
        </foreach>
    </delete>

    <#-- update -->
    <update id="updateByPrimaryKey">
        update ${table.tableName}
        <set>
        <#list table.insertSelectiveColumnList as column>
            ${column.columnName} = ${'#\{'}${column.property},jdbcType=${column.jdbcType}}<#if column_has_next>,</#if>
        </#list>
        </set>
        where ${idColumn.columnName} = ${'#\{'}${idColumn.property},jdbcType=${idColumn.jdbcType}}
    </update>

    <update id="updateByPrimaryKeySelective">
        update ${table.tableName}
        <set>
        <#list table.insertSelectiveColumnList as column>
            <if test="${column.property} != null">
                ${column.columnName} = ${'#\{'}${column.property},jdbcType=${column.jdbcType}}<#if column_has_next>,</#if>
            </if>
        </#list>
        </set>
        where ${idColumn.columnName} = ${'#\{'}${idColumn.property},jdbcType=${idColumn.jdbcType}}
    </update>

    <#-- select -->
    <select id="selectByPrimaryKey" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from ${table.tableName}
        where ${idColumn.columnName} = ${'#\{'}${idColumn.property},jdbcType=${idColumn.jdbcType}}
    </select>

    <select id="selectByPrimaryKeys" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from ${table.tableName} where ${idColumn.columnName} in
        <foreach close=")" collection="list" item="item" open="(" separator=",">
            ${'#\{'}item}
        </foreach>
    </select>

    <select id="selectByRecord" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from ${table.tableName}
        <where>
        <#list table.insertSelectiveColumnList as column>
            <if test="${column.property} != null">
                and ${column.columnName} = ${'#\{'}${column.property}}
            </if>
        </#list>
        </where>
        <#if table.modelType??>
            <#if table.modelType.type=="Sortable">
            <#assign sortColumn = table.modelType.getColumn("sort")>
            order by ${sortColumn.columnName}
            </#if>
            <#if table.modelType.type=="Treeable">
            <#assign sortColumn = table.modelType.getColumn("sort")>
            <#assign parentColumn = table.modelType.getColumn("parent")>
            order by ${parentColumn.columnName}, ${sortColumn.columnName}
            </#if>
        </#if>
    </select>

    <select id="selectByConditions" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from ${table.tableName}
        <where>
        <#list table.insertSelectiveColumnList as column>
            <if test="${column.property} != null">
                and ${column.columnName} ${'$\{'}${column.property}}
            </if>
        </#list>
        </where>
        <#if table.modelType??>
            <#if table.modelType.type=="Sortable">
            <#assign sortColumn = table.modelType.getColumn("sort")>
            order by ${sortColumn.columnName}
            </#if>
            <#if table.modelType.type=="Treeable">
            <#assign sortColumn = table.modelType.getColumn("sort")>
            <#assign parentColumn = table.modelType.getColumn("parent")>
            order by ${parentColumn.columnName}, ${sortColumn.columnName}
            </#if>
        <#else>
            <if test="orderBy != null">
            order by ${'$\{'}orderBy}
            </if>
        </#if>
    </select>

    <select id="selectAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from ${table.tableName}
        <#if table.modelType??>
            <#if table.modelType.type=="Sortable">
                <#assign sortColumn = table.modelType.getColumn("sort")>
        order by ${sortColumn.columnName}
            </#if>
            <#if table.modelType.type=="Treeable">
                <#assign sortColumn = table.modelType.getColumn("sort")>
                <#assign parentColumn = table.modelType.getColumn("parent")>
        order by ${parentColumn.columnName}, ${sortColumn.columnName}
            </#if>
        </#if>
    </select>

    <#-- batch -->
    <insert id="batchInsert" keyProperty="${idColumn.property}" useGeneratedKeys="true">
        insert into ${table.tableName} (${table.insertColumnList}) values
        <foreach collection="list" item="item" separator=",">
            (
        <#list table.insertSelectiveColumnList as column>
            ${'#\{item.'}${column.property},jdbcType=${column.jdbcType}}<#if column_has_next>,</#if>
        </#list>
            )
        </foreach>
    </insert>

    <update id="batchUpdate">
        <foreach close="" collection="list" item="item" open="" separator=";">
            update ${table.tableName}
            <set>
            <#list table.insertSelectiveColumnList as column>
                <if test="item.${column.property} != null">
                    ${column.columnName} = ${'#\{item.'}${column.property},jdbcType=${column.jdbcType}}<#if column_has_next>,</#if>
                </if>
            </#list>
            </set>
            where ${idColumn.columnName} = ${'#\{item.'}${idColumn.property},jdbcType=${idColumn.jdbcType}}
        </foreach>
    </update>

    <#-- statistical -->
    <select id="count" resultType="java.lang.Long">
        select count(*)
        from ${table.tableName}
    </select>
    <#-- model type -->
    <#if table.modelType??>
        <#-- Sortable -->
        <#if table.modelType.type=="Sortable">
        <#assign sortColumn = table.modelType.getColumn("sort")>

    <update id="exchange">
        <if test="source.${idColumn.property} != target.${idColumn.property}">
            UPDATE ${table.tableName} SET ${sortColumn.columnName} = ${'#\{target.'}${sortColumn.property}} WHERE ${idColumn.columnName} = ${'#\{source.'}${idColumn.property}};
            UPDATE ${table.tableName} SET ${sortColumn.columnName} = ${'#\{source.'}${sortColumn.property}} WHERE ${idColumn.columnName} = ${'#\{target.'}${idColumn.property}};
        </if>
    </update>

    <update id="move">
        <if test="from.${idColumn.property} != to.${idColumn.property}">
            <if test="from.${sortColumn.property} > to.${sortColumn.property}">
                UPDATE ${table.tableName} SET ${sortColumn.columnName} = ${sortColumn.columnName} + 1
                WHERE ${sortColumn.columnName} >= ${'#\{to.'}${sortColumn.property}} and ${sortColumn.columnName} <![CDATA[ < ]]> ${'#\{from.'}${sortColumn.property}};
            </if>
            <if test="to.${sortColumn.property} > from.${sortColumn.property}">
                UPDATE ${table.tableName} SET ${sortColumn.columnName} = ${sortColumn.columnName} - 1
                WHERE ${sortColumn.columnName} > ${'#\{from.'}${sortColumn.property}} and ${sortColumn.columnName} <![CDATA[ <= ]]> ${'#\{to.'}${sortColumn.property}};
            </if>
            UPDATE ${table.tableName} SET ${sortColumn.columnName} = ${'#\{to.'}${sortColumn.property}} WHERE ${idColumn.columnName} = ${'#\{from.'}${idColumn.property}}
        </if>
    </update>

    <select id="selectPrevious" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM ${table.tableName} WHERE ${sortColumn.columnName} = (
            SELECT MAX(${sortColumn.columnName}) FROM ${table.tableName} WHERE ${sortColumn.columnName} <![CDATA[ < ]]> ${'#\{'}${sortColumn.property}}
        )
    </select>

    <select id="selectNext" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM ${table.tableName} WHERE ${sortColumn.columnName} = (
            SELECT MIN(${sortColumn.columnName}) FROM ${table.tableName} WHERE ${sortColumn.columnName} <![CDATA[ > ]]> ${'#\{'}${sortColumn.property}}
        )
    </select>

    <select id="selectFirst" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM ${table.tableName} WHERE ${sortColumn.columnName} = (
            SELECT MIN(${sortColumn.columnName}) FROM ${table.tableName}
        )
    </select>

    <select id="selectLast" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM ${table.tableName} WHERE ${sortColumn.columnName} = (
            SELECT MAX(${sortColumn.columnName}) FROM ${table.tableName}
        )
    </select>
        </#if>
        <#-- Treeable -->
        <#if table.modelType.type=="Treeable">
            <#assign parentColumn = table.modelType.getColumn("parent")>
            <#assign pathColumn = table.modelType.getColumn("path")>
            <#assign sortColumn = table.modelType.getColumn("sort")>

    <update id="exchange">
        <if test="source.${idColumn.property} != target.${idColumn.property} and source.${parentColumn.property} == target.${parentColumn.property}">
            UPDATE ${table.tableName} SET ${sortColumn.columnName} = ${'#\{target.'}${sortColumn.property}} WHERE ${idColumn.columnName} = ${'#\{source.'}${idColumn.property}};
            UPDATE ${table.tableName} SET ${sortColumn.columnName} = ${'#\{source.'}${sortColumn.property}} WHERE ${idColumn.columnName} = ${'#\{target.'}${idColumn.property}}
        </if>
    </update>

    <update id="move">
        <if test="from.${idColumn.property} != to.${idColumn.property} and from.${parentColumn.property} == to.${parentColumn.property}">
            <if test="from.${sortColumn.property} > to.${sortColumn.property}">
                UPDATE ${table.tableName} SET ${sortColumn.columnName} = ${sortColumn.columnName} + 1
                WHERE ${sortColumn.columnName} >= ${'#\{to.'}${sortColumn.property}}
                AND ${parentColumn.columnName} = ${'#\{from.'}${parentColumn.property}}
                AND ${sortColumn.columnName} <![CDATA[ < ]]> ${'#\{from.'}${sortColumn.property}};
            </if>
            <if test="to.${sortColumn.property} > from.${sortColumn.property}">
                UPDATE ${table.tableName} SET ${sortColumn.columnName} = ${sortColumn.columnName} - 1
                WHERE ${sortColumn.columnName} > ${'#\{from.'}${sortColumn.property}}
                AND ${parentColumn.columnName} = ${'#\{from.'}${parentColumn.property}}
                AND ${sortColumn.columnName} <![CDATA[ <= ]]> ${'#\{to.'}${sortColumn.property}};
            </if>
            <if test="to.${sortColumn.property} != from.${sortColumn.property}">
                UPDATE ${table.tableName} SET ${sortColumn.columnName} = ${'#\{to.'}${sortColumn.property}} WHERE ${idColumn.columnName} = ${'#\{from.'}${idColumn.property}}
            </if>
        </if>
    </update>

    <update id="updateChildrenPath">
        UPDATE ${table.tableName}
        SET ${pathColumn.columnName} = CONCAT(${'#\{'}${pathColumn.property}},SUBSTR(${pathColumn.columnName},LENGTH(${'#\{'}oldPath}) + 1, LENGTH(${pathColumn.columnName})))
        WHERE ${parentColumn.columnName} = ${'#\{'}${idColumn.property}}
    </update>

    <select id="selectChildren" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM
        ${table.tableName}
        <where>
            <choose>
                <when test="deep">
                    ${parentColumn.columnName} like '${'$\{entity.'}${parentColumn.property}}%'
                    AND ${idColumn.columnName} != ${'#\{entity.'}${idColumn.property}}
                </when>
                <otherwise>
                    ${parentColumn.columnName} = ${'#\{entity.'}${idColumn.property}}
                </otherwise>
            </choose>
        </where>
        order by ${parentColumn.columnName}, ${sortColumn.columnName}
    </select>

    <select id="selectPrevious" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM
        ${table.tableName}
        WHERE
        ${sortColumn.columnName} = (
            SELECT
            MAX(${sortColumn.columnName})
            FROM
            ${table.tableName}
            WHERE
            ${parentColumn.columnName} = ${'#\{'}${parentColumn.property}}
            AND ${sortColumn.columnName} <![CDATA[ < ]]> ${'#\{'}${sortColumn.property}}
        )
        AND ${parentColumn.columnName} = ${'#\{'}${parentColumn.property}}
    </select>

    <select id="selectNext" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM
        ${table.tableName}
        WHERE
        ${sortColumn.columnName} = (
            SELECT
            MIN(${sortColumn.columnName})
            FROM
            ${table.tableName}
            WHERE
            ${parentColumn.columnName} = ${'#\{'}${parentColumn.property}}
            AND ${sortColumn.columnName} <![CDATA[ > ]]> ${'#\{'}${sortColumn.property}}
        )
        AND ${parentColumn.columnName} = ${'#\{'}${parentColumn.property}}
    </select>

    <select id="selectFirst" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM
        ${table.tableName}
        WHERE
        ${sortColumn.columnName} = (
            SELECT
            MIN(${sortColumn.columnName})
            FROM
            ${table.tableName}
            WHERE
            ${parentColumn.columnName} = ${'#\{'}${parentColumn.property}}
        )
        AND ${parentColumn.columnName} = ${'#\{'}${parentColumn.property}}
    </select>

    <select id="selectLast" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List" />
        FROM
        ${table.tableName}
        WHERE
        ${sortColumn.columnName} = (
            SELECT
            MAX(${sortColumn.columnName})
            FROM
            ${table.tableName}
            WHERE
            ${parentColumn.columnName} = ${'#\{'}${parentColumn.property}}
        )
        AND ${parentColumn.columnName} = ${'#\{'}${parentColumn.property}}
    </select>
        </#if>
    </#if>
</mapper>